package org.origin.centre.security.token;

import org.origin.centre.security.user.XUser;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.oauth2.jwt.JwtClaimsSet;
import org.springframework.security.oauth2.server.authorization.OAuth2TokenType;
import org.springframework.security.oauth2.server.authorization.token.JwtEncodingContext;
import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenCustomizer;

import java.util.Optional;

/**
 * jwt token customizer
 *
 * @author ferret
 * @version 2024-05-08
 */
@SuppressWarnings("ClassCanBeRecord")
public class JwtTokenCustomizer implements OAuth2TokenCustomizer<JwtEncodingContext> {
    protected final String cacheKey;
    protected final RedisTemplate<Object, Object> redisTemplate;

    public JwtTokenCustomizer(RedisTemplate<Object, Object> redisTemplate, String cacheKey) {
        this.redisTemplate = redisTemplate;
        this.cacheKey = cacheKey;
    }

    public String getRedisKey(String userId) {
        return cacheKey + userId;
    }

    @Override
    public void customize(JwtEncodingContext context) {
        if (OAuth2TokenType.ACCESS_TOKEN.equals(context.getTokenType()) && context.getPrincipal() instanceof UsernamePasswordAuthenticationToken) {
            // Customize headers/claims for access_token
            Optional.ofNullable(context.getPrincipal().getPrincipal()).ifPresent(principal -> {
                JwtClaimsSet.Builder claims = context.getClaims();
                if (principal instanceof XUser userDetails) {
                    claims.subject(userDetails.getId());
                    // 将登录成功的用户信息存redis缓存
                    redisTemplate.opsForValue().set(getRedisKey(userDetails.getId()), userDetails.getCacheMap());
                    // 系统用户添加自定义字段
                    // claims.claim(XConst.ID, userDetails.getId());
                    // claims.claim(XConst.ACCOUNT, userDetails.getUsername());
                    // 这里存入角色至JWT，解析JWT的角色用于鉴权的位置
                    // if (userDetails.getOrgId() != null) claims.claim(XConst.ORG_ID, userDetails.getOrgId());
                    // if (userDetails.getDataScope() != null) claims.claim(XConst.DATA_SCOPE, userDetails.getDataScope());
                    // if (userDetails.getAuthorities() != null) claims.claim(XConst.AUTHORITIES, userDetails.getAuthorities());
                }
            });
        }
    }

}
